<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>网页版2048</title>
    <style>
        header {
            display: block;
            margin: 0 auto;
            width: 100%;
            text-align: center;
        }

        header h1 {
            font-family: Arial;
            font-size: 60px;
            font-weight: bold;
            margin: 0 auto;
        }

        header #new_game_button {
            display: block;
            margin: 0px auto;
            width: 100px;
            padding: 10px 10px;
            background-color: #8f7a66;
            font-family: Arial;
            color: white;
            border-radius: 10px;
            text-decoration: none;
        }

        header #new_game_button:hover {
            background-color: #9f8b77;
        }

        header p {
            font-family: Arial;
            font-size: 25px;
            margin: 5px auto;
        }

        #grid_container {
            width: 460px;
            height: 460px;
            padding: 20px;
            margin: 0px auto;
            background-color: #bbada0;
            border-radius: 10px;
            position: relative;
        }

        .grid_cell {
            width: 100px;
            height: 100px;
            border-radius: 6px;
            background-color: #ccc0b3;
            position: absolute;
        }

        .number_cell {
            border-radius: 6px;
            font-family: Arial;
            font-weight: bold;
            font-size: 60px;
            line-height: 100px;
            text-align: center;
            position: absolute;
        }
        footer{
            display: block;
            margin: 0px auto;
            width: 100px;
            padding: 10px 10px;

            font-family: Arial;
            color: white;
            border-radius: 10px;
            text-decoration: none;
        }
    </style>
    <script src="https://cdn.bootcss.com/jquery/1.9.0/jquery.js"></script>
    <script>
        document_width = window.screen.availWidth;
        grid_container_width = 0.92 * document_width;
        cell_side_length = 0.18 * document_width;
        cell_space = 0.04 * document_width;

        function get_pos_top(i, j) {
            return cell_space + i * (cell_space + cell_side_length);
        }

        function get_pos_left(i, j) {
            return cell_space + j * (cell_space + cell_side_length);
        }



        function finalText(number){
            if(myText!=""){
                switch (number) {
                    case 2: return myText[0]; break;
                    case 4: return myText[1]; break;
                    case 8: return myText[2]; break;
                    case 16: return myText[3]; break;
                    case 32: return myText[4]; break;
                    case 64: return myText[5]; break;
                    case 128: return myText[6]; break;
                    case 256: return myText[7]; break;
                    case 512: return myText[8]; break;
                    case 1024: return myText[9]; break;
                    case 2048: return myText[10]; break;
                    case 4096: return myText[11]; break;
                    case 8192: return myText[12]; break;
                }
            }else{
                return number;
            }
        }

        function get_number_background_color(number) {
            switch (number) {
                case 2: return '#eee4da'; break;
                case 4: return '#ede0c8'; break;
                case 8: return '#f2b179'; break;
                case 16: return '#f59563'; break;
                case 32: return '#f67c5f'; break;
                case 64: return '#f65e3b'; break;
                case 128: return '#edcf72'; break;
                case 256: return '#edcc61'; break;
                case 512: return '#9c0'; break;
                case 1024: return '#33b5e5'; break;
                case 2048: return '#09c'; break;
                case 4096: return '#a6c'; break;
                case 8192: return '#93c'; break;
            }
            return 'black';
        }

        function get_number_color(number) {
            if (number <= 4)
                return '#776e65';
            return 'white';
        }

        function nospace(board) {
            for (var i = 0; i < 4; i++) {
                for (var j = 0; j < 4; j++) {
                    if (board[i][j] == 0) {
                        return false;
                    }
                }
            }
            return true;
        }

        function can_move_left(board) {
            for (var i = 0; i < 4; i++) {
                for (var j = 1; j < 4; j++) {
                    if (board[i][j] != 0) {
                        if (board[i][j - 1] == 0 || board[i][j] == board[i][j - 1]) {
                            return true;
                        }
                    }
                }
            }
            return false;
        }

        function can_move_right(board) {
            for (var i = 0; i < 4; i++) {
                for (var j = 2; j >= 0; j--) {
                    if (board[i][j] != 0) {
                        if (board[i][j + 1] == 0 || board[i][j] == board[i][j + 1]) {
                            return true;
                        }
                    }
                }
            }
            return false;
        }

        function can_move_up(board) {
            for (var j = 0; j < 4; j++) {
                for (var i = 1; i < 4; i++) {
                    if (board[i][j] != 0) {
                        if (board[i - 1][j] == 0 || board[i - 1][j] == board[i][j]) {
                            return true;
                        }
                    }
                }
            }
            return false;
        }

        function can_move_down(board) {
            for (var j = 0; j < 4; j++) {
                for (var i = 2; i >= 0; i--) {
                    if (board[i][j] != 0) {
                        if (board[i + 1][j] == 0 || board[i + 1][j] == board[i][j]) {
                            return true;
                        }
                    }
                }
            }
            return false;
        }

        function no_block_horizontal(row, col1, col2, board) {
            for (var i = col1 + 1; i < col2; i++) {
                if (board[row][i] != 0) {
                    return false;
                }
            }
            return true;
        }

        function no_block_vertical(col, row1, row2, board) {
            for (var i = row1 + 1; i < row2; i++) {
                if (board[i][col] != 0) {
                    return false;
                }
            }
            return true;
        }

        function nomove(board) {
            if (can_move_down(board) || can_move_up(board) || can_move_right(board) || can_move_left(board)) {
                return false;
            }
            return true;
        }
        function show_number_with_animation(i, j, rand_number) {
            var number_cell = $('#number_cell_' + i + '_' + j);
            number_cell.css('background-color', get_number_background_color(rand_number));
            number_cell.css('color', get_number_color(rand_number));
            //替换显示
            number_cell.text( finalText(rand_number));
            //number_cell.text(rand_number);
            number_cell.animate({
                width: cell_side_length,
                height: cell_side_length,
                top: get_pos_top(i, j),
                left: get_pos_left(i, j)
            }, 50);
        }

        function show_move_animation(fromx, fromy, tox, toy) {
            var number_cell = $('#number_cell_' + fromx + '_' + fromy);
            number_cell.animate({
                top: get_pos_top(tox, toy),
                left: get_pos_left(tox, toy)
            }, 200);
        }

        function update_score(score) {
            $('#score').text(score);
        }
        var myText =  ["菜鸟", "入门", "码畜", "码奴", "码农", "IT民工", "IT工程师", "IT人才", "IT精英", "IT大哥", "IT领袖"];
        //["工兵", "班长", "排长", "连长", "营长", "团长", "旅长", "师长", "军长", "司令", "军旗"]
        var board = new Array();
        var score = 0;
        var has_conflicted = new Array();
        var startx = 0;
        var starty = 0;
        var endx = 0;
        var endy = 0;
        var success_string = 'Success';
        var gameover_string = 'GameOver';

        $(document).ready(function() {
            prepare_for_mobile();
            new_game();
        });

        function new_game() {
            //初始化棋盘
            init();
            //在随机两个格子生成数字
            generate_one_number();
            generate_one_number();
        }

        function init() {
            for (var i = 0; i < 4; i++) {
                for (var j = 0; j < 4; j++) {
                    var grid_cell = $('#grid_cell_' + i + '_' + j);
                    grid_cell.css('top', get_pos_top(i, j));
                    grid_cell.css('left', get_pos_left(i, j));
                }
            }
            for (var i = 0; i < 4; i++) {
                board[i] = new Array();
                has_conflicted[i] = new Array();
                for (var j =0; j < 4; j++) {
                    board[i][j] = 0;
                    has_conflicted[i][j] = false;
                }
            }
            update_board_view();
            score = 0;
            update_score(score);
        }

        function update_board_view() {
            $('.number_cell').remove();
            for (var i = 0; i < 4; i++) {
                for (var j = 0; j < 4; j++) {
                    $('#grid_container').append('<div class="number_cell" id="number_cell_' + i + '_' + j + '"></div>');
                    var number_cell = $('#number_cell_' + i + '_' + j);
                    if (board[i][j] == 0) {
                        number_cell.css('width', '0px');
                        number_cell.css('height', '0px');
                        number_cell.css('top', get_pos_top(i, j) + cell_side_length / 2);
                        number_cell.css('left', get_pos_left(i, j) + cell_side_length / 2);
                    } else {
                        number_cell.css('width', cell_side_length);
                        number_cell.css('height', cell_side_length);
                        number_cell.css('top', get_pos_top(i, j));
                        number_cell.css('left', get_pos_left(i, j));
                        number_cell.css('background-color', get_number_background_color(board[i][j]));
                        number_cell.css('color', get_number_color(board[i][j]));
                        //替换显示
                        number_cell.text( finalText(board[i][j]));
                       // number_cell.text(board[i][j]);
                    }
                    has_conflicted[i][j] = false;
                }
            }
            $('.number_cell').css('line-height', cell_side_length + 'px');
            $('.number_cell').css('font-size', 0.3 * cell_side_length + 'px');
        }

        function generate_one_number() {
            if (nospace(board)) {
                return false;
            }
            //随机一个位置
            var randx = parseInt(Math.floor(Math.random() * 4));
            var randy = parseInt(Math.floor(Math.random() * 4));
            var time = 0;
            while (time < 50) {
                if (board[randx][randy] == 0) {
                    break;
                }
                randx = parseInt(Math.floor(Math.random() * 4));
                randy = parseInt(Math.floor(Math.random() * 4));
                time++;
            }
            if (time == 50) {
                for (var i = 0; i < 4; i++) {
                    for (var j = 0; j < 4; j++) {
                        if (board[i][j] == 0) {
                            randx = i;
                            randy = j;
                        }
                    }
                }
            }
            //随机一个数字
            var rand_number = Math.random() < 0.5 ? 2 : 4;
            //在随机位置显示随机数字
            board[randx][randy] = rand_number;
            show_number_with_animation(randx, randy, rand_number);
            return true;
        }

        $(document).keydown(function(event) {
            if ($('#score').text() == success_string) {
                new_game();
                return;
            }
            switch (event.keyCode) {
                case 37: //left
                    event.preventDefault();
                    if (move_left()) {
                        setTimeout('generate_one_number()', 210);
                        setTimeout('is_gameover()', 300);
                    }
                    break;
                case 38: //up
                    event.preventDefault();
                    if (move_up()) {
                        setTimeout('generate_one_number()', 210);
                        setTimeout('is_gameover()', 300);
                    }
                    break;
                case 39: //right
                    event.preventDefault();
                    if (move_right()) {
                        setTimeout('generate_one_number()', 210);
                        setTimeout('is_gameover()', 300);
                    }
                    break;
                case 40: //down
                    event.preventDefault();
                    if (move_down()) {
                        setTimeout('generate_one_number()', 210);
                        setTimeout('is_gameover()', 300);
                    }
                    break;
                default:
                    break;
            }
        });

        document.addEventListener('touchstart', function(event) {
            startx = event.touches[0].pageX;
            starty = event.touches[0].pageY;
        });

        document.addEventListener('touchmove', function(event) {
            event.preventDefault();
        });

        document.addEventListener('touchend', function(event) {
            endx = event.changedTouches[0].pageX;
            endy = event.changedTouches[0].pageY;

            var deltax = endx - startx;
            var deltay = endy - starty;
            if (Math.abs(deltax) < 0.3 * document_width && Math.abs(deltay) < 0.3 * document_width) {
                return;
            }
            if ($('#score').text() == success_string) {
                new_game();
                return;
            }
            //x
            if (Math.abs(deltax) >= Math.abs(deltay)) {
                if (deltax > 0) {
                    //move right
                    if (move_right()) {
                        setTimeout('generate_one_number()', 210);
                        setTimeout('is_gameover()', 300);
                    }
                } else {
                    //move left
                    if (move_left()) {
                        setTimeout('generate_one_number()', 210);
                        setTimeout('is_gameover()', 300);
                    }
                }
            } else {	//y
                if (deltay > 0) {
                    //move down
                    if (move_down()) {
                        setTimeout('generate_one_number()', 210);
                        setTimeout('is_gameover()', 300);
                    }
                } else {
                    //move up
                    if (move_up()) {
                        setTimeout('generate_one_number()', 210);
                        setTimeout('is_gameover()', 300);
                    }
                }
            }
        });

        function move_left() {
            if (!can_move_left(board)) {
                return false;
            }
            //move left
            for (var i = 0; i < 4; i++) {
                for (var j = 1; j < 4; j++) {
                    if (board[i][j] != 0) {
                        for (var k = 0; k < j; k++) {
                            if (board[i][k] == 0 && no_block_horizontal(i, k, j, board)) {
                                show_move_animation(i, j, i, k);
                                board[i][k] = board[i][j];
                                board[i][j] = 0;
                                break;
                            } else if (board[i][k] == board[i][j] && no_block_horizontal(i, k, j, board) && !has_conflicted[i][k]) {
                                show_move_animation(i, j, i, k);
                                board[i][k] += board[i][j]
                                board[i][j] = 0;
                                //add score
                                score += board[i][k];
                                update_score(score);
                                has_conflicted[i][k] = true;
                                break;
                            }
                        }
                    }
                }
            }
            setTimeout('update_board_view()', 200);
            return true;
        }

        function move_right() {
            if (!can_move_right(board)) {
                return false;
            }
            //move right
            for (var i = 0; i < 4; i++) {
                for (var j = 2; j >= 0; j--) {
                    if (board[i][j] != 0) {
                        for (var k = 3; k > j; k--) {
                            if (board[i][k] == 0 && no_block_horizontal(i, j, k, board)) {
                                show_move_animation(i, j, i, k);
                                board[i][k] = board[i][j];
                                board[i][j] = 0;
                                break;
                            } else if (board[i][k] == board[i][j] && no_block_horizontal(i, j, k, board) && !has_conflicted[i][k]) {
                                show_move_animation(i, j, i, k);
                                board[i][k] += board[i][j];
                                board[i][j] = 0;
                                //add score
                                score += board[i][k];
                                update_score(score);
                                has_conflicted[i][k] = true;
                                break;
                            }
                        }
                    }
                }
            }
            setTimeout('update_board_view()', 200);
            return true;
        }

        function move_up() {
            if (!can_move_up(board)) {
                return false;
            }
            //move up
            for (var j = 0; j < 4; j++) {
                for (var i = 1; i < 4; i++) {
                    if (board[i][j] != 0) {
                        for (var k = 0; k < i; k++) {
                            if (board[k][j] == 0 && no_block_vertical(j, k, i, board)) {
                                show_move_animation(i, j, k, j);
                                board[k][j] = board[i][j];
                                board[i][j] = 0;
                                break;
                            } else if (board[k][j] == board[i][j] && no_block_vertical(j, k, i, board) && !has_conflicted[k][j]) {
                                show_move_animation(i, j, k, j);
                                board[k][j] += board[i][j];
                                board[i][j] = 0;
                                //add score
                                score += board[k][j];
                                update_score(score);
                                has_conflicted[k][j] = true;
                                break;
                            }
                        }
                    }
                }
            }
            setTimeout('update_board_view()', 200);
            return true;
        }

        function move_down() {
            if (!can_move_down(board)) {
                return false;
            }
            //move down
            for (var j = 0; j < 4; j++) {
                for (var i = 2; i >= 0; i--) {
                    if (board[i][j] != 0) {
                        for (var k = 3; k > i; k--) {
                            if (board[k][j] == 0 && no_block_vertical(j, i, k, board)) {
                                show_move_animation(i, j, k, j);
                                board[k][j] = board[i][j];
                                board[i][j] = 0;
                                break;
                            } else if (board[k][j] == board[i][j] && no_block_vertical(j, i, k, board) && !has_conflicted[k][j]) {
                                show_move_animation(i, j, k, j);
                                board[k][j] += board[i][j];
                                board[i][j] = 0;
                                //add score
                                score += board[k][j];
                                update_score(score);
                                has_conflicted[k][j] = true;
                                break;
                            }
                        }
                    }
                }
            }
            setTimeout('update_board_view()', 200);
            return true;
        }

        function is_gameover() {
            for (var i = 0; i < 4; i++) {
                for (var j = 0; j < 4; j++) {
                    if (board[i][j] == 2048) {
                        update_score(success_string);
                        return;
                    }
                }
            }
            if (nospace(board) && nomove(board)) {
                gameover();
            }
        }

        function gameover() {
            update_score(gameover_string);
        }

        function prepare_for_mobile() {
            if (document_width > 500) {
                grid_container_width = 500;
                cell_side_length = 100;
                cell_space = 20;
            }
            $('#grid_container').css('width', grid_container_width - 2 * cell_space);
            $('#grid_container').css('height', grid_container_width - 2 * cell_space);
            $('#grid_container').css('padding', cell_space);
            $('#grid_container').css('border-radius', 0.02 * grid_container_width);
            $('.grid_cell').css('width', cell_side_length);
            $('.grid_cell').css('height', cell_side_length);
            $('.grid_cell').css('border-radius', 0.02 * grid_container_width);
        }


    </script>
</head>
<body>
<header>
    <h1>2048</h1>
    <a href="javascript:new_game();" id="new_game_button">New Game</a>
    <p>score: <span id="score">0</span></p>
</header>
<div id="grid_container">
    <div class="grid_cell" id="grid_cell_0_0"></div>
    <div class="grid_cell" id="grid_cell_0_1"></div>
    <div class="grid_cell" id="grid_cell_0_2"></div>
    <div class="grid_cell" id="grid_cell_0_3"></div>
    <div class="grid_cell" id="grid_cell_1_0"></div>
    <div class="grid_cell" id="grid_cell_1_1"></div>
    <div class="grid_cell" id="grid_cell_1_2"></div>
    <div class="grid_cell" id="grid_cell_1_3"></div>
    <div class="grid_cell" id="grid_cell_2_0"></div>
    <div class="grid_cell" id="grid_cell_2_1"></div>
    <div class="grid_cell" id="grid_cell_2_2"></div>
    <div class="grid_cell" id="grid_cell_2_3"></div>
    <div class="grid_cell" id="grid_cell_3_0"></div>
    <div class="grid_cell" id="grid_cell_3_1"></div>
    <div class="grid_cell" id="grid_cell_3_2"></div>
    <div class="grid_cell" id="grid_cell_3_3"></div>
</div>
</body>
</html>